#include "utils.h"

#include <QtCore/QString>
#include <QtCore/QTextStream>

#include "CNetworkManager.h"
#include "CNet.h"

/*----------------------------------------------------------------------------*/

CNetworkManager::CNetworkManager()
	:	m_net( NULL )
	,	m_isTerminated( false )
{
}


/*----------------------------------------------------------------------------*/


CNetworkManager::~CNetworkManager()
{
	if ( m_net )
		delete m_net;
}


/*----------------------------------------------------------------------------*/


void CNetworkManager::TrainNetwork( ImageV& _images,  double _speed, double _threshold )
{
	m_isTerminated = false;
	double error = 0.0;	
	do
	{
		error = 0.0;
		for ( size_t i = 0; i < _images.size(); i++ )
		{
			m_net->Train( _speed, _images[i] );			
			error += m_net->GetMeanSquareError();
		}
		error /= _images.size();		

		QString errorString;		
		QTextStream(&errorString)<<"Mean square error: "<<error;		
		emit Progress( errorString );
	} while ( error > _threshold && !m_isTerminated );
	if ( m_isTerminated )
		emit Progress( "Training terminated." );
	else
		emit Progress( "Training successfully done." );
}


/*----------------------------------------------------------------------------*/


void CNetworkManager::CreateNetwork( int _inputsNum, const IntV& _neuronsNumber )
{
	if ( m_net )
	{
		delete m_net;
		m_networkFileName.clear();		
	}

	m_net = new CNet( _inputsNum, _neuronsNumber );
}


/*----------------------------------------------------------------------------*/


bool CNetworkManager::NetworkExists() const
{
	return m_net != NULL;
}


/*----------------------------------------------------------------------------*/


const std::string& CNetworkManager::GetNetworkFileName() const
{
	return m_networkFileName;
}


/*----------------------------------------------------------------------------*/


void CNetworkManager::SaveNetwork( const std::string& _fileName )
{
	m_networkFileName = _fileName;
	std::ofstream outputFile( m_networkFileName.c_str(), std::ios::out | std::ios::binary );
	m_net->SaveToFile( outputFile );
	outputFile.close();
}


/*----------------------------------------------------------------------------*/


void CNetworkManager::LoadNetwork( const std::string& _fileName )
{
	m_networkFileName = _fileName;

	if ( m_net )	
		delete m_net;		

	std::ifstream inputFile( m_networkFileName.c_str(), std::ios::in | std::ios::binary );
	m_net = new CNet( inputFile );
	inputFile.close();
}


/*----------------------------------------------------------------------------*/


void CNetworkManager::CloseNetwork()
{
	if ( m_net )
	{
		delete m_net;
		m_networkFileName.clear();
	}
	m_net = NULL;
}


/*----------------------------------------------------------------------------*/


void CNetworkManager::Terminate()
{
	m_isTerminated = true;
}


/*----------------------------------------------------------------------------*/


char CNetworkManager::ClassifyImage( CImage& _image )
{
	m_net->Calculate( &_image );
	return m_net->GetMaxOutput() + 'A';
}


/*----------------------------------------------------------------------------*/


